package com.ruoyi.system.service;

import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.bean.Domain;
import com.ruoyi.common.exception.RegisterProcessingException;
import com.ruoyi.system.domain.MrDevice;
import com.ruoyi.system.domain.MrDeviceAlarmData;
import com.ruoyi.system.domain.MrMonitorDevicePointValue;

import java.util.List;

/**
 * 网关上行数据处理接口
 * @author lsw
 */
public interface SensorDataService {
    /**
     * 更新通道状态信息
     *
     * @param port 设备端口
     */
    void updateDeviceStatus(String port);

    /**
     * 处理寄存器数据（支持单/双寄存器）
     *
     * @param registerAddress 寄存器地址字符串（格式如"40001"或"40001-40002"）
     * @param startAdd        起始地址
     * @param regisData       寄存器数据列表
     * @param deviceId        设备ID（用于日志）
     * @param jsonObject      原始JSON数据（用于日志）
     * @return 处理后的寄存器值
     * @throws RegisterProcessingException 当处理失败时抛出
     */
    String processRegisterValue(String registerAddress, int startAdd, List<String> regisData, String deviceId, JSONObject jsonObject) throws RegisterProcessingException;

    /**
     * 校验设备数据参数是否有效
     *
     * @param regisData  寄存器数据
     * @param startAdd   起始地址
     * @param device     设备对象
     * @param jsonObject 原始JSON数据
     * @return true-参数有效，false-参数无效
     */
    boolean validateDeviceParameters(List<String> regisData, Integer startAdd, MrDevice device, JSONObject jsonObject);

    /**
     * 检查设备是否需要跳过处理（基于延时时间配置）
     *
     * @param device 设备对象
     * @param delayTime 默认延时时间
     * @return true-需要跳过处理，false-不需要跳过
     */
    boolean shouldSkipByDelayTime(MrDevice device, int delayTime);

    /**
     * 处理数据，包括保存网关上行数据、保存设备报警信息和更新设备状态信息
     * @param mrMonitorDevicePointValues 网关上行数据列表
     * @param mrDeviceAlarmDatas 设备报警信息列表
     * @param mrDeviceList 设备状态信息列表
     */
    void gatewayBatchData(List<MrMonitorDevicePointValue> mrMonitorDevicePointValues, List<MrDeviceAlarmData> mrDeviceAlarmDatas, List<MrDevice> mrDeviceList);

    /**
     * 处理 XDR 协议的数据
     * 数据示例：
     * $--XDR,S,0,,0,S,0,,1,S,0,,2,S,1,,3,S,1,,4,S,0,,5,S,1,,6,S,1,,7,S,1,,8,S,1,,9,S,0,,10,S,1,,11,S,1,,12,S,1,,13,S,1,,14,S,1,,15,S,0,,16,S,1,,17,S,1,,18,S,1,,19,S,0,,20,S,1,,21,S,1,,22,S,1,,23,S,0,,24,S,0,,25*4E
     * @param mr 包含产品信息的对象
     * @return 处理后的值
     */
    String processXdrData(MrDevice mr);

    /**
     * 处理 LDAXDR 协议的数据
     * 自动舵的报警板VDR实测数据
     * $LDAXDR,0000,0000,*2B    (解读:所有各点全无报警）
     * $LDAXDR,0102,1300,*2A    (解读:X2为1是1#电源、X4为2是2#断相、X5为1是1#液压阻塞、X6为3是1#失油压、2#失油压,其他各点都没有报警和显示）
     * @param mr 包含产品信息的对象
     * @return 处理后的值
     */
    String processLdaxdrData(MrDevice mr);

    /**
     * 处理设备开关相关数据
     * @param mr 包含设备信息的对象
     * @param value 设备数据
     * @return 处理后的值
     */
    String processDeviceSwitchData(MrDevice mr, String value);

    /**
     * 处理 0183 - VDR 协议的数据
     * $SBMT,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,xxxx,xxxx,xxxx,xxxx,xxx,<CR><LF>
     *                       1 控制位置 =30H 驾驶室遥控，=31H 集控室遥控，=32H 机旁控制
     *                       2 操纵器手柄位置 =30H 停车位置，=31H 正车位置，=32H 倒车位置
     *                       3 控制输出 =30H 停车 =31H 正车 =32H 倒车
     *                       4 齿轮箱工作状态 =30H 停车位置，=31H 正车位置，=32H 倒车位置
     *                       5 =30H 正常 =31H 故障停车
     *                       6 =30H 正常 =31H 故障降速
     *                       7 =30H 正常 =31H 应急停车
     *                       8 =30H 正常 =31H 应急操纵
     *                       9 =30H 正常 =31H 超速
     *                       10=30H 正常 =31H 失速
     *                       11=30H 正常 =31H 操纵器故障
     *                       12=30H 正常 =31H 测速传感器故障
     *                       13=30H 正常 =31H 错向报警
     *                       14=30H 正常 =31H 失气/失电报警
     *                       15 备用
     *                       16 操纵器命令转速 4 个 ASCII 数字字符
     *                       17 主机实际转速反馈 4 个 ASCII 数字字符
     *                       18 尾轴实际转速反馈 4 个 ASCII 数字字符
     *                       19 转速控制输出 3 个 ASCII 数字字符
     *                       20 备用 4 个 ASCII 数字字符
     *                       无通讯认为遥控系统计算机不工作或故障
     * @param mr 包含设备信息的对象
     * @return 处理后的值
     */
    String process0183VdrData(MrDevice mr);

    /**
     * 处理 0183 协议的数据
     * 协议示例：
     * $PSGA,2,1,A,0,0,0,0,0,1,0,0,0,0,0,0,0*76
     * $PSGA,2,2,B,1,0,0,0,0,0,0,0,0,0,0,0,0*76
     * @param mr 包含设备信息的对象
     * @return 处理后的值，如果符合条件返回 "true"，否则返回 null
     */
    String process0183Data(MrDevice mr);

    /**
     * 处理 Modbus 协议的数据
     * @param mr 包含设备信息的对象
     * @param value 原始数据值
     * @return 处理后的数据值
     */
    String processModbusData(MrDevice mr, String value);

    /**
     * 处理硬接点模块的数据
     * @param value 原始数据值
     * @return 处理后的数据值
     */
    String processHardContactModuleData(String value);

    /**
     * 处理 0 - 10V 电压采样模块的数据
     * 0-30V电压采样模块解析方法是先16进制数转换成10进制后，最前面的数代表小数点位数，有效数据4位，
     * （1）比如21823，读成18.23V
     * （2）比如31023，读成1.023V
     * （3）比如43152，读成0.3152V
     * 注：第1位代表小数点的只可能是2、3、4这3个数，其他的数不可能能出现
     * @param value 原始数据值
     * @return 处理后的数据值
     */
    String processVoltageSamplingModuleData(String value);

    /**
     * 处理 PT100 设备的数据
     * @param value 原始数据值
     * @return 处理后的数据值
     */
    String processPt100Data(String value);

    /**
     * 处理 4 - 20mA 输出设备的数据
     * @param mr 包含设备信息的对象
     * @param value 原始数据值
     * @return 处理后的数据值
     */
    String processFourToTwentyMaOutputData(MrDevice mr, String value);

    /**
     * 处理 4 - 20mA 设备的数据
     * @param mr 包含设备信息的对象
     * @param value 原始数据值
     * @return 处理后的数据值
     */
    String processFourToTwentyMaData(MrDevice mr, String value);

    /**
     * 处理不同模式和产品类型的数据
     * @param mr 包含设备信息的对象
     * @param value 原始数据值
     * @return 处理后的数据值
     */
    String processData(MrDevice mr, String value);

    /**
     * 处理功能码并设置 MrDevice 的相关属性
     * @param jsonObject 包含设备信息的 JSON 对象
     * @param mrDevice 设备信息对象
     */
    void processFunctionCode(JSONObject jsonObject, MrDevice mrDevice);

    /**
     * 监测是否为主机
     * @return 结果
     */
    boolean checkConnect();

    /**
     * 设备最后报警时间
     * @param systemId 设备id
     * @return 最后报警时间
     */
    long getLastWarnTime(String systemId);

    /**
     * 报警轮机员输出
     *
     * @param systemId systemId
     */
    void marineEngineer(String systemId, String type);

    /**
     * 关联报警
     *
     * @param systemId systemId
     */
    void associatedAlarm(String systemId, boolean flag);

    /**
     * redis 处理
     *
     * @param key   systemId
     * @param value 报警内容
     */
    void saveRedis(String key, String value);

    /**
     * 报警蜂鸣器输出
     *
     * @param mr      设备信息
     * @param content 报警内容
     */
    void buzzerOutput(MrDevice mr, String content);

    /**
     * 通道报警
     *
     * @param port 通道端口
     */
    void channelAlarm(int port);

    /**
     * 检查阈值报警
     * @param domain 包含当前值的域对象
     * @param mrDevice 设备配置信息
     * @return 是否触发任何报警
     */
    String checkThresholdAlarm(Domain domain, MrDevice mrDevice);

    /**
     * 主推网关上行处理
     *
     * @param domain 上行数据
     */
    void dataUpload(Domain domain, List<MrMonitorDevicePointValue> mrMonitorDevicePointValues, List<MrDeviceAlarmData> mrDeviceAlarmDatas, List<MrDevice> mrDeviceList);

    /**
     * 处理网关上行数据
     * @param jsonObject 网关数据
     */
    void processGatewayUpstreamData(JSONObject jsonObject);

    /**
     * 设备数据处理
     *
     * @param domainList 上行数据
     */
    void dataProcessing(List<Domain> domainList);

    /**
     * 网关下发配置
     {
     "msg": "操作成功",
     "code": 200,
     "data": {
     "up_ports": [
     {
     "baudrate": 9600,
     "data": [
     {
     "reg_num": 33,
     "slave_addr": 1,
     "func_code": 2,
     "start_addr": 65
     },
     {
     "reg_num": 38,
     "slave_addr": 2,
     "func_code": 3,
     "start_addr": 55
     }
     ],
     "serial_port": 0,
     "dev_port": 11001
     },
     {
     "baudrate": 9600,
     "data": [
     {
     "reg_num": 33,
     "slave_addr": 1,
     "func_code": 2,
     "start_addr": 65
     }
     ],
     "serial_port": 2,
     "dev_port": 11003
     },
     {
     "baudrate": 9600,
     "data": [
     {
     "reg_num": 33,
     "slave_addr": 1,
     "func_code": 2,
     "start_addr": 65
     }
     ],
     "serial_port": 3,
     "dev_port": 11004
     },
     {
     "baudrate": 9600,
     "data": [
     {
     "reg_num": 33,
     "slave_addr": 1,
     "func_code": 2,
     "start_addr": 65
     }
     ],
     "serial_port": 4,
     "dev_port": 11005
     },
     {
     "baudrate": 9600,
     "data": [
     {
     "reg_num": 33,
     "slave_addr": 1,
     "func_code": 2,
     "start_addr": 65
     }
     ],
     "serial_port": 5,
     "dev_port": 11006
     }
     ],
     "down_ports": [
     {
     "baudrate": 38400,
     "listen_port": 502,
     "serial_port": 1,
     "dev_port": 11002
     }
     ]
     }
     }
     * @param devSn 网关设备的dev_sn
     * @return 网关配置
     */
    JSONObject configuration(String devSn);

    /**
     * {"device_ip":"192.168.1.88","timestamp":"707711","interfaces":[{"name":"eth0","status":"up"},{"name":"eth1","status":"down"}]}
     * @param jsonObject 网关心跳
     */
    void heartbeatDetection(JSONObject jsonObject);

    /**
     * 十进制转十六位二进制
     *
     * @param value 十进制
     * @return 十六位二进制
     */
    char[] getChars(String value);
}
